#! /usr/bin/env python

import sys
from optparse import OptionParser
import random


class LotteryCore:
    def __init__(self, seed=0, jobs=3, jlist='', maxlen=10, maxticket=100, quantum=1, compute=True):
        parser = OptionParser()
        parser.add_option('-s', '--seed', default=seed, help='the random seed', action='store', type='int', dest='seed')
        parser.add_option('-j', '--jobs', default=jobs, help='number of jobs in the system', action='store', type='int',
                          dest='jobs')
        parser.add_option('-l', '--jlist', default=jlist,
                          help='instead of random jobs, provide a comma-separated list of run times and ticket values (e.g., 10:100,20:100 would have two jobs with run-times of 10 and 20, each with 100 tickets)',
                          action='store', type='string', dest='jlist')
        parser.add_option('-m', '--maxlen', default=maxlen, help='max length of job', action='store', type='int', dest='maxlen')
        parser.add_option('-T', '--maxticket', default=maxticket, help='maximum ticket value, if randomly assigned', action='store',
                          type='int', dest='maxticket')
        parser.add_option('-q', '--quantum', default=quantum, help='length of time slice', action='store', type='int', dest='quantum')
        parser.add_option('-c', '--compute', help='compute answers for me', action='store_true', default=compute, dest='solve')

        (self.options, self.args) = parser.parse_args()
        self.deal_args()

    def deal_args(self):
        options = self.options
        random.seed(options.seed)

        print('作业列表如下:')

        tickTotal = 0
        runTotal = 0
        joblist = []
        if options.jlist == '':
            for jobnum in range(0, options.jobs):
                runtime = 0
                while runtime == 0:
                    runtime = int(options.maxlen * random.random())
                tickets = 0
                while tickets == 0:
                    tickets = int(options.maxticket * random.random())
                runTotal += runtime
                tickTotal += tickets
                joblist.append([jobnum, runtime, tickets])
                print('  作业%d ( 长度 = %d, 彩票数 = %d )' % (jobnum, runtime, tickets))
        else:
            jobnum = 0
            for entry in options.jlist.split(','):
                (runtime, tickets) = entry.split(':')
                joblist.append([jobnum, int(runtime), int(tickets)])
                runTotal += int(runtime)
                tickTotal += int(tickets)
                jobnum += 1
            for job in joblist:
                print('  作业%d ( 长度 = %d, 彩票数 = %d )' % (job[0], job[1], job[2]))

        if options.solve is False:
            print('这里列出的随机数你可能会用到:')
            for i in range(runTotal):
                r = int(random.random() * 1000001)
                print('随机', r)

        if options.solve:
            print('** 解答 **\n')

            jobs = len(joblist)
            clock = 0
            for i in range(runTotal):
                r = int(random.random() * 1000001)
                winner = int(r % tickTotal)

                current = 0
                for (job, runtime, tickets) in joblist:
                    current += tickets
                    if current > winner:
                        (wjob, wrun, wtix) = (job, runtime, tickets)
                        break

                print('随机', r, '-> 赢得彩票 %d (共 %d) -> 运行 %d' % (winner, tickTotal, wjob))
                # print 'Winning ticket %d (of %d) -> Run %d' % (winner, tickTotal, wjob)

                print('  作业:', end=' ')
                for (job, runtime, tickets) in joblist:
                    if wjob == job:
                        wstr = '*'
                    else:
                        wstr = ' '

                    if runtime > 0:
                        tstr = tickets
                    else:
                        tstr = '---'
                    print(' (%s 作业:%d timeleft:%d tix:%s ) ' % (wstr, job, runtime, tstr), end=' ')
                print('')

                # now do the accounting
                if wrun >= options.quantum:
                    wrun -= options.quantum
                else:
                    wrun = 0

                clock += options.quantum

                # job completed!
                if wrun == 0:
                    print('--> 作业%d 在 %d 时完成' % (wjob, clock))
                    tickTotal -= wtix
                    wtix = 0
                    jobs -= 1

                # update job list
                joblist[wjob] = (wjob, wrun, wtix)

                if jobs == 0:
                    print('')
                    break


def main():
    core = LotteryCore()


if __name__ == "__main__":
    main()
